import React, { Component } from 'react';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import
{
    BoxGeometry, Mesh, MeshBasicMaterial, TextureLoader,
    Scene, SphereGeometry, WebGLRenderer, ArrowHelper, Vector3, Camera, PerspectiveCamera, SpriteMaterial, Sprite, Vector2
} from 'three';
import scene_right from '../../assets/img/scene_right.jpeg';
import scene_left from '../../assets/img/scene_left.jpeg';
import scene_back from '../../assets/img/scene_back.jpeg';
import scene_front from '../../assets/img/scene_front.jpeg';
import scene_top from '../../assets/img/scene_top.jpeg';
import scene_bottom from '../../assets/img/scene_bottom.jpeg';
import hot from '../../assets/img/hot.png';
import { Raycaster } from 'three';
import nextScene from '../../assets/img/nextScene.svg';

@observer
export default class WebVR extends Component<{}, {}>
{
    constructor(props: any)
    {
        super(props);
    }
    @observable myScene = document.getElementById("vrScene") as HTMLDivElement;
    /*
        ThreeJS最重要的三个东西
    */
    @observable scene = new Scene(); // 场景
    @observable camera = new PerspectiveCamera(
        75, //视野角度
        this.myScene.offsetWidth / this.myScene.offsetHeight, //长宽比
        0.1, //近截面
        1000 //远截面
    );
    @observable renderer = new WebGLRenderer(); //渲染器


    geometryCube = new BoxGeometry(100, 100, 100); //几何图形:建一个什么样的形状,这是一个正方体
    geometrySphere = new SphereGeometry(40, 40, 40); //这是一个球体s
    materials: MeshBasicMaterial[] = [  //材质的选择决定是否受光照影响
        new MeshBasicMaterial({ map: new TextureLoader().load(scene_left) }),
        new MeshBasicMaterial({ map: new TextureLoader().load(scene_right) }),
        new MeshBasicMaterial({ map: new TextureLoader().load(scene_top) }),
        new MeshBasicMaterial({ map: new TextureLoader().load(scene_bottom) }),
        new MeshBasicMaterial({ map: new TextureLoader().load(scene_front) }),
        new MeshBasicMaterial({ map: new TextureLoader().load(scene_back, () => { this.loop(); }) }),
    ];
    @observable control = new OrbitControls(this.camera, this.renderer.domElement);//控制相机到处看
    //三根辅助箭头
    arrowHelperY = new ArrowHelper(new Vector3(0, 1, 0), new Vector3(0, 0, 0), 250, 0x00ff00);
    arrowHelperX = new ArrowHelper(new Vector3(1, 0, 0), new Vector3(0, 0, 0), 250, 0xff0000);
    arrowHelperZ = new ArrowHelper(new Vector3(0, 0, 1), new Vector3(0, 0, 0), 250, 0x0000ff);
    @observable cube = new Mesh(this.geometryCube, this.materials);
    pointMaterial = new SpriteMaterial({ map: new TextureLoader().load(nextScene, () => { this.loop(); }) });

    hotPoints = [
        {
            position: {
                x: -3,
                y: 0,
                z: -45
            },
            detail: {
                "title": "门"
            }
        },
        {
            position: {
                x: -40,
                y: -10,
                z: 45
            },
            detail: {
                "title": "电视机"
            }
        }
    ];
    @observable poiOb: Sprite[] = [];

    @action
    setUp = (scene: Scene, camera: Camera, renderer: WebGLRenderer, el: HTMLDivElement) =>
    {
        // let cube = new Mesh(this.geometryCube, this.materials);
        this.cube.geometry.scale(1, 1, -1); //贴图反转到里面
        scene.add(this.cube);

        scene.add(this.arrowHelperY);
        scene.add(this.arrowHelperX);
        scene.add(this.arrowHelperZ);

        this.hotPoints.forEach(element =>
        {
            let sprite = new Sprite(this.pointMaterial);
            sprite.scale.set(10, 10, 10);
            sprite.position.set(element.position.x, element.position.y, element.position.z);
            sprite.userData = element.detail;
            this.poiOb.push(sprite);
            scene.add(sprite);
        });


        //设置渲染器的尺寸,就是canvas的宽高
        renderer.setSize(el.offsetWidth, el.offsetHeight);
        //设置canvas的背景颜色就是场景背景颜色(???但是为什么不是scene里面设置呢?)
        this.renderer.setClearColor(0xb9d3ff, 1);
        el.appendChild(renderer.domElement);

        camera.position.set(0, 0, 10);
        camera.lookAt(scene.position);

        this.loop();
    };

    raycast = (e: React.MouseEvent<HTMLDivElement>) =>
    {
        let canvas = e.target as HTMLCanvasElement;
        e.preventDefault();

        let raycaster = new Raycaster();
        let mouse = new Vector2();
        console.log(e.clientX);
        //将鼠标点击位置的屏幕坐标转成threejs中的标准坐标
        mouse.x = ((e.clientX - 256) / canvas.clientWidth) * 2 - 1;
        mouse.y = -(e.clientY / canvas.clientHeight) * 2 + 1;

        raycaster.setFromCamera(mouse, this.camera);
        let intersect = raycaster.intersectObjects(this.poiOb);

        if (intersect.length > 0)
        {
            window.alert(`您点击了${intersect[0].object.userData.title}`);
        }

    };


    loop = () =>
    {
        this.renderer.render(this.scene, this.camera);
    };

    componentDidMount()
    {
        this.setUp(this.scene, this.camera, this.renderer, this.myScene);
        this.control.addEventListener('change', this.loop);

    }

    render()
    {
        return (
            <div onClick={(e) => { this.raycast(e); }} id="vrScene" style={{ width: "100%", height: "100%" }}>
            </div>
        );
    }
}
